package main

import (
	"fmt"
	"math/rand"
	"sort"
	"strconv"
	"time"
)

type Students struct {
	Name string
	Age  int
}

// 新的切片类型
type StudentsSlice []Students // 做新类型定义，如果是类型别名是没办法给新类型提供方法
// 给新类型定义方法，让它实现sort包中的Interface接口的3个函数功能
func (x StudentsSlice) Len() int           { return len(x) }
func (x StudentsSlice) Swap(i, j int)      { x[i], x[j] = x[j], x[i] }
func (x StudentsSlice) Less(i, j int) bool { return x[i].Age < x[j].Age }

// struct 排序1，使用sort.Sort实现
func structsort1(stu []Students) {
	// 做结构体排序，就是基于结构体的某个字段排序
	sort.Sort(StudentsSlice(stu)) // 强制做类型转换为StudentsSlice类型
	fmt.Printf("structsort1: %+v, %[1]T\n", stu)
}

// struct 排序2
func structsort2(stu []Students) {
	sort.Slice(stu, func(i, j int) bool {
		return stu[i].Age < stu[j].Age
	})
	fmt.Printf("structsort2: %+v, %[1]T\n", stu)
}

func main() {
	r := rand.New(rand.NewSource(time.Now().UnixNano()))
	students := make([]Students, 0, 5)
	for i := 0; i < 5; i++ {
		name := "Tom" + strconv.Itoa(i)
		age := r.Intn(30) + 30
		students = append(students, Students{Name: name, Age: age})
	}
	fmt.Printf("main: %+v, %[1]T\n", students)
	fmt.Println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~")
	structsort1(students)
	structsort2(students)
}
